#include "USB.hpp"
#include "FreeRTOS.hpp"

uint8_t buff[40];
Froce_Type froce = {0, 0};
#ifdef AT32
extern usbd_core_type usb_core_dev;
void Send_report(reprot_type *data, uint8_t len)
{
    memcpy(buff, data, len);
    custom_hid_class_send_report(&usb_core_dev, (uint8_t *)buff, len);
}
#endif
#ifdef CH32
void Send_report(reprot_type *data, uint8_t len)
{
    uint8_t Timeout = 0;
    while (USBHS_Endp1_Up_Flag == 1)
    {
        vTaskDelay(1);
        Timeout++;
        if (Timeout > 5)
        {
            break;
        }
    };
    memcpy(buff, data, len);
    Ep1_Tx(buff, len);
    // printf("Tx1\n");
}

void USB_Printf(const char *str, ...)
{
    uint8_t Timeout = 0;
    while (USBHS_Endp2_Up_Flag == 1)
    {
        Timeout++;
        if (Timeout > 5)
        {
            break;
        }
    }
    {
        char strFormatted[256];
        uint16_t str_size;
        va_list args;        //存放可变参数的数据结构
        va_start(args, str); //初始化可变参数,需要传一个va_list类型变量,和可变参数之前的参数,这里是str
        str_size = vsprintf(strFormatted, str, args);
        Ep2_Tx((uint8_t *)strFormatted, str_size);
        va_end(args);
        // printf("Tx2\n");
    }
}
#endif

#ifdef STM32
extern USBD_HandleTypeDef hUsbDeviceFS;
void Send_report(reprot_type *data, uint8_t len)
{
    memcpy(buff, data, len);
    USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, buff, len);
}

#endif

extern void configchange(out_reprot *new_settings);
extern void wheel_config_changed(Wheel_config *wheel_config_t);

void Froce_Callback(uint8_t Flag, int16_t Value)
{
    froce.Flag = Flag;
    froce.Froce = Value;
    // USB_Printf("Froce %d\n", Value);
}

out_reprot new_settings;
void USB_Control_Out_Callback(void *temp)
{
    memcpy(&new_settings, temp, sizeof(new_settings));
    configchange(&new_settings);
}
Wheel_config wheel_config_t;
void USB_Wheel_Out_Callback(void *temp)
{
    memcpy(&wheel_config_t, temp, sizeof(wheel_config_t));
    wheel_config_changed(&wheel_config_t);
}

void Hid_Output_Callback(uint8_t *reprot)
{
    // USB_Printf("%d %d %d %d\n",reprot[0],reprot[1],reprot[2],reprot[3]);
    switch (reprot[0])
    {
    case 0x01:
#ifdef CH32
        SetEffect(reprot[1], EP1_Rx_Databuf);
#endif
        break;
    case 0x05:
        Froce_Callback(0x01, reprot[2] + (reprot[3] << 8));
        break;
    case 0x08:
        switch (reprot[2])
        {
        case 1:
            // Op Effect Start
            break;
        case 2:
            // Op Effect Start Solo
            break;
        case 3:
            // Op Effect Stop
            Froce_Callback(0, 0);
            break;
        }
        break;
    case 0x0a:
        switch (reprot[1])
        {
        case 1:
            // DC Enable
            break;
        case 2:
            // DC Disable
            break;
        case 3:
            // DC Stop All Effects
            Froce_Callback(0, 0);
            break;
        case 4:
            // DC Device Reset
            break;
        case 5:
            // DC Device Pause
            break;
        case 6:
            // DC Device Continue
            break;
        default:
            break;
        }
        break;
    case 0x0c:
        break;
    case 0x0d:
        USB_Control_Out_Callback(reprot);
        break;
    case 0x0e:
        USB_Wheel_Out_Callback(reprot);
        break;
    default:
        printf("ID : %d \n", reprot[0]);
        break;
    }
}
